﻿using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace VideoTools
{
    public abstract class NotifyPropertyBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        readonly Dictionary<string, object> _dictionary = new Dictionary<string, object>();

        protected T Get<T>(T Default = default, [CallerMemberName] string PropertyName = "")
        {
            lock (_dictionary)
            {
                if (_dictionary.TryGetValue(PropertyName, out var obj) && obj is T val)
                {
                    return val;
                }
            }

            return Default;
        }
        protected bool Set<T>(ref T Field, T Value, [CallerMemberName] string PropertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(Field, Value))
                return false;

            Field = Value;

            OnPropertyChanged(PropertyName);

            return true;
        }
        protected void Set<T>(T Value, [CallerMemberName] string PropertyName = "")
        {
            lock (_dictionary)
            {
                if (_dictionary.ContainsKey(PropertyName))
                {
                    _dictionary[PropertyName] = Value;
                }
                else
                    _dictionary.Add(PropertyName, Value);
            }

            OnPropertyChanged(PropertyName);
        }
        protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = "")
        {
            if (EqualityComparer<T>.Default.Equals(storage, value))
                return false;

            storage = value;
            NotifyPropertyChanged(propertyName);
            return true;
        }

        public void OnPropertyChanged(string propertyName) =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName ?? string.Empty));

        public void NotifyPropertyChanged(params string[] propertyNames)
        {
            foreach (string propertyName in propertyNames)
            {
                OnPropertyChanged(propertyName);
            }
        }
    }
}
